using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace Common.Shared.Windows.Forms
{

	#region Public Enumerations
	[Flags]
	public enum SHAutoCompleteFlags : uint
	{	
		/// <summary>
		/// SHACF_FILESYSTEM | SHACF_URLALL
		/// </summary>
		SHACF_DEFAULT = 0x0,                          
		/// <summary>
		/// This includes the File System as well as the rest of the shell (Desktop\My Computer\Control Panel\)
		/// </summary>
		SHACF_FILESYSTEM = 0x1,                        
		/// <summary>
		/// URLs in the User's History
		/// </summary>
		SHACF_URLHISTORY = 0x2,                        
		/// <summary>
		/// URLs in the User's Recently Used list.
		/// </summary>
		SHACF_URLMRU = 0x4,                            
		/// <summary>
		/// Use the tab to move thru the autocomplete possibilities instead 
		/// of to the next dialog/window control.
		/// </summary>
		SHACF_USETAB = 0x8,              
		/// <summary>
		/// Include URLs in the User's Recently Used List and the URL
		/// History
		/// </summary>
		SHACF_URLALL = (SHACF_URLHISTORY | SHACF_URLMRU),
		/// <summary>
		/// This includes the File System
		/// </summary>
		SHACF_FILESYS_ONLY = 0x10,
		/// <summary>
		/// Same as SHACF_FILESYS_ONLY except it only includes directories, 
		/// UNC servers, and UNC server shares.
		/// </summary>
		SHACF_FILESYS_DIRS = 0x20,
		/// <summary>
		/// Ignore the registry default and force the feature on.
		/// </summary>
		SHACF_AUTOSUGGEST_FORCE_ON = 0x10000000,
		/// <summary>
		/// Ignore the registry default and force the feature off.
		/// </summary>
		SHACF_AUTOSUGGEST_FORCE_OFF = 0x20000000,
		/// <summary>
		/// Ignore the registry default and force the feature on. 			
		/// </summary>
		SHACF_AUTOAPPEND_FORCE_ON = 0x40000000, 
		/// <summary>
		/// Ignore the registry default and force the feature off.
		/// </summary>
		SHACF_AUTOAPPEND_FORCE_OFF = 0x80000000 
	}
	#endregion

	#region AutoCompleteTextBox
	/// <summary>
	/// Adds Shell File System and URL AutoCompletion facilities to 
	/// a text box
	/// </summary>
	public class AutoCompleteTextBox : TextBox 
	{
		#region Unmanaged Code		
		[DllImport("shlwapi.dll")]
		private static extern int SHAutoComplete (
			IntPtr hwndEdit, 
			SHAutoCompleteFlags dwFlags );

		#endregion

		#region Member Variables
		private SHAutoCompleteFlags autoCompleteFlags = 
			SHAutoCompleteFlags.SHACF_FILESYS_ONLY;
		private bool flagsSet = false;
		private bool handleCreated = false;
		#endregion

		#region Implementation

		/// <summary>
		/// Gets/sets the flags controlling automcompletion for the 
		/// text box
		/// </summary>
		public SHAutoCompleteFlags AutoCompleteFlags
		{
			get
			{
				return this.autoCompleteFlags;
			}
			set
			{
				this.autoCompleteFlags = value;
				this.flagsSet = true;
				if (handleCreated)
				{
					SetAutoComplete();
				}
			}
		}

		protected override void OnHandleCreated ( EventArgs e )
		{
			// call this first as SHAutoComplete may not be supported
			// on the OS
			base.OnHandleCreated(e);
			// don't do anything if we're in design mode:
			if (!this.DesignMode)
			{
				// remember we've created the handle for any future 
				// get/ set
				handleCreated = true;

				// if we've provided some flags then start autocompletion:
				if (flagsSet)
				{
					SetAutoComplete();
				}
			}
		}

		private void SetAutoComplete()
		{
			SHAutoComplete(this.Handle, this.autoCompleteFlags);
		}

		/// <summary>
		///  Constructs an auto-complete capable text box but
		///  does not automatically start auto-completion.
		/// </summary>
		public AutoCompleteTextBox() : base()
		{
		}

		/// <summary>
		/// Constructs an auto-complete capable text box and
		/// starts auto-completion with the specified flags.
		/// </summary>
		/// <param name="autoCompleteFlags">Flags controlling
		/// auto-completion</param>
		public AutoCompleteTextBox(
			SHAutoCompleteFlags autoCompleteFlags
			) : this()
		{
			// Handle will not be available at this point; we need
			// to wait for HandleCreated:
			this.autoCompleteFlags = autoCompleteFlags;
			this.flagsSet = true;
		}

		#endregion
	}
	#endregion
}

